CC = gcc
CXX = g++
LINKER ?= gcc
AR = ar crv
RM = rm -f 
MV = mv -f
CP = cp -f

define ECHO
    @printf "\033[;32m"; printf $1; printf "\033[0m\n"
endef

CFLAGS ?= -Wall -c -std=c99 -D_POSIX_C_SOURCE=2 $(C_FLAG)
CPPFLAGS ?= -Wall -c -std=c++98 $(CPP_FLAG)
ELFLAGS ?= $(EL_FLAG)
DLFLAGS ?= -shared -fPIC 
INCLUDES += -I$(MKHOME)/include $(INCLUDE)
LIBS += -L$(MKHOME)/lib $(LIB)

ifeq ($(LINK_TYPE), exec)
    ifeq ($(OS), Windows_NT)
        FINAL_TARGET = $(TARGET).exe
    else
        FINAL_TARGET = $(TARGET)
    endif
endif

ifeq ($(LINK_TYPE), dynamic)
    ifeq ($(OS), Windows_NT)
        FINAL_TARGET = lib$(TARGET).dll
    else
        FINAL_TARGET = lib$(TARGET).so 
    endif
endif

ifeq ($(LINK_TYPE), static)
    FINAL_TARGET = lib$(TARGET).a
endif

debug: CFLAGS += -g
debug: CPPFLAGS += -g
debug: $(FINAL_TARGET)

release: CFLAGS += -O2 -fno-strict-aliasing
release: CPPFLAGS += -O2
release: $(FINAL_TARGET)

$(FINAL_TARGET): $(OBJS)
ifeq ($(LINK_TYPE), exec)
	@$(call ECHO, "[linking exec $(TARGET) ...]")
	$(LINKER) -o $(FINAL_TARGET) $(ELFLAGS) $^ $(LIBS)
else ifeq ($(LINK_TYPE), static)
	@$(call ECHO, "[linking static $(FINAL_TARGET) ...]")
	$(AR) $(FINAL_TARGET) $^
	@$(CP) $(FINAL_TARGET) $(MKHOME)/lib
else ifeq ($(LINK_TYPE), dynamic)
	@$(call ECHO, "[linking dynamic $(FINAL_TARGET) ...]")
	$(LINKER) -o $(FINAL_TARGET) $(DLFLAGS) $^ $(LIBS) 
	@$(CP) $(FINAL_TARGET) $(MKHOME)/lib
endif

%.o: %.c
	@$(call ECHO, "[compiling $@ ...]")
	$(CC) -o $@ $(CFLAGS) $(INCLUDES) $<

%.o: %.cc
	@$(call ECHO, "[compiling $@ ...]")
	$(CXX) -o $@ $(CPPFLAGS) $(INCLUDES) $<

clean:
	@$(call ECHO, "[cleaning $(OBJS) $(FINAL_TARGET)...]")
	@$(RM) $(OBJS) $(FINAL_TARGET)

run:
	@./$(FINAL_TARGET)

dbg:
	@gdb ./$(FINAL_TARGET)
